home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 15 / BBS in a box XV-2.iso / Files II / Prog / N-P / NIFTY.sit / NIFTY / myCShell / floatingWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-23  |  13.6 KB  |  617 lines  |  [TEXT/KAHL]

  1. /*********************************************************
  2.  "floatingWindow.c"
  3.  
  4.  adapted from the pioneering work by:
  5.  
  6.      Don Melton & Mike Ritter [MacTutor, April, 1988]
  7.      ... and ...
  8.     Thomas Fruin             [MacTutor, December 1988]
  9.      ... and ...
  10.     Patrick Doane             [his "FLOATING WINDOWS", Version 1.3,]
  11.                              [downloaded from "America OnLine"    ]
  12.  
  13.  using Symantec's "THINK C", v 5.00
  14.  *********************************************************/
  15.  
  16.  
  17. #include "protos"
  18.  
  19. #include "globals.h"
  20. #include "extern.h"
  21.  
  22. #include "floatingWindow.h"
  23.  
  24.  
  25. WindowPeek        frontToolWindow,
  26.                 backToolWindow,
  27.                 frontDocWindow;
  28.  
  29.  
  30.  
  31.  
  32. void    TInitWindows (void)        {
  33.  
  34.  
  35.     frontToolWindow =
  36.     backToolWindow  =
  37.     frontDocWindow  = nil;
  38.     
  39. }    /* TInitWindows */
  40.  
  41.  
  42.  
  43. WindowPtr    TMakeNewTool (short windowID, Ptr wStorage, WindowPtr behind)    {
  44.                            
  45.         WindowPtr    theWindow;
  46.         
  47.  
  48.     if (!gMac2)        theWindow = GetNewWindow  (windowID, wStorage, behind);
  49.     else            theWindow = GetNewCWindow (windowID, wStorage, behind);
  50.                                        
  51.     if (theWindow != nil)    {
  52.         ((WindowPeek) theWindow)->windowKind = toolKind;
  53.         if ( ((WindowPeek) theWindow)->visible )    TShowWindow(theWindow);
  54.     }
  55.         
  56.     return (theWindow);
  57.  
  58. }    /* TMakeNewTool */
  59.  
  60.  
  61.  
  62. void    TCloseWindow (WindowPtr theWindow)        {
  63.  
  64.  
  65.     // Reset our globals such as frontToolWindow:
  66.     THideWindow(theWindow);
  67.     CloseOurWindow(theWindow);
  68.         
  69. }    /* TCloseWindow */
  70.  
  71.  
  72.  
  73. void    TSelectWindow (WindowPtr whichWindow)        {
  74.  
  75.         WindowPeek        whichPWindow, theFrontWindow;
  76.         short            whichWKind, frontWKind;
  77.         
  78.         
  79.     whichPWindow = (WindowPeek) whichWindow;
  80.     theFrontWindow = (WindowPeek) gFW;
  81.     whichWKind = TGetWKind(whichPWindow);
  82.     frontWKind = TGetWKind(theFrontWindow);
  83.     
  84.     if (whichWKind == toolKind)    {
  85.         
  86.         THiliteTools(true);
  87.  
  88.         if (frontWKind == systemKind)    {
  89.             // Send DA(s) behind frontDocWindow OR backToolWindow:
  90.             if (frontDocWindow != nil)
  91.                     TSendDAsBack(frontDocWindow);
  92.             else    TSendDAsBack(backToolWindow);
  93.  
  94.             CurDeactive = (WindowPtr) theFrontWindow;
  95.             HiliteWindow(CurDeactive, false);
  96.         }
  97.         
  98.         else    /* Window is a tool window, with NO DA on top */
  99.             ;
  100.     
  101.         if ((frontToolWindow != backToolWindow) /* more than one */ &&
  102.             (whichPWindow == backToolWindow))
  103.             backToolWindow = TPrevVisWindow(whichPWindow);
  104.         if (whichPWindow != frontToolWindow)    BringToFront(whichWindow);
  105.         frontToolWindow = whichPWindow;
  106.  
  107.         if (frontDocWindow != nil)    {
  108.             CurActivate = (WindowPtr) frontDocWindow;
  109.             HiliteWindow(CurActivate, true);
  110.         }
  111.         
  112.     }    /* end: toolKind */
  113.     
  114.     else if (whichWKind == userKind)    {
  115.  
  116.         THiliteTools(true);
  117.         
  118.         if (frontWKind == systemKind)    {
  119.             /* Window is a document window, or a modeless
  120.             ** dialog window, with a Desk Accessory on top. */
  121.             
  122.             if (frontToolWindow)    {
  123.                     if (whichPWindow != frontDocWindow)
  124.                         TBringForward(whichPWindow, backToolWindow, normalCalc);
  125.                     TSendDAsBack(whichPWindow);
  126.             }
  127.             else    TSendDAsBack(whichPWindow);
  128.  
  129.             CurDeactive = (WindowPtr) theFrontWindow;
  130.             HiliteWindow(CurDeactive, false);
  131.         }    /* systemKind */
  132.         
  133.         else    {
  134.             /* Window is a document window, or a modeless
  135.             ** dialog window, with NO DA on top.          */
  136.                         
  137.             if (frontToolWindow == nil)
  138.                 SelectWindow(whichWindow);
  139.             else    {
  140.                 if (whichPWindow != frontDocWindow)
  141.                     TBringForward(whichPWindow, backToolWindow, normalCalc);
  142.                 if (frontDocWindow && (whichPWindow != frontDocWindow))        {
  143.                     CurDeactive = (WindowPtr) frontDocWindow;
  144.                     HiliteWindow(CurDeactive, false);
  145.                 }
  146.             }
  147.         }    /* NO DA on top */
  148.  
  149.         frontDocWindow = whichPWindow;
  150.         CurActivate = (WindowPtr) whichPWindow;
  151.         HiliteWindow(CurActivate, true);
  152.         
  153.     }    /* end: userKind */
  154.     
  155.     else    /* systemKind */    {
  156.  
  157.         /* DAs do their own thing !! */
  158.         
  159.     }
  160.                             
  161. }    /* TSelectWindow */
  162.  
  163.  
  164.  
  165. void    THideWindow (WindowPtr theWindow)        {
  166.  
  167.  
  168.     if (theWindow == (WindowPtr)frontToolWindow)    {
  169.         if (frontToolWindow == backToolWindow)        /* Just one to begin with !! */
  170.             frontToolWindow = backToolWindow = nil;
  171.         else
  172.             frontToolWindow = TNextVisWindow(toolKind, frontToolWindow);
  173.         ;
  174.         HideWindow(theWindow);        /* Generates Activate Event. */
  175.     }
  176.         
  177.     else if (TGetWKind((WindowPeek)theWindow) == toolKind)    {
  178.         /* A Tool Window in back: */
  179.         
  180.         if ((WindowPeek)theWindow == backToolWindow)
  181.             backToolWindow = TPrevVisWindow((WindowPeek)theWindow);
  182.         ;
  183.         ShowHide(theWindow, false);
  184.     }
  185.  
  186.     else    /* userKind */    {
  187.     
  188.             WindowPeek    newFrontDocWindow;
  189.             
  190.     
  191.         newFrontDocWindow = TNextVisWindow(userKind, frontDocWindow);
  192.         
  193.         if (frontToolWindow)    {
  194.                 // So we don't deactivate a hidden window:
  195.                 frontDocWindow = nil;
  196.                 ShowHide(theWindow, false);
  197.                 // Set up globals, CurActivate & CurDeactive:
  198.                 if (newFrontDocWindow)    TSelectWindow((WindowPtr)newFrontDocWindow);
  199.         }
  200.         else    {
  201.             HideWindow(theWindow);
  202.             frontDocWindow = newFrontDocWindow;
  203.         }
  204.             
  205.     }    /* userKind */
  206.  
  207. }    /* THideWindow */
  208.  
  209.  
  210.  
  211. void    TShowWindow (WindowPtr theWindow)        {
  212.  
  213.  
  214.     if (TGetWKind((WindowPeek)theWindow) == toolKind)    {
  215.         if (frontToolWindow == nil)
  216.             frontToolWindow = backToolWindow = (WindowPeek)theWindow;
  217.         else
  218.             frontToolWindow = (WindowPeek)theWindow;
  219.         ;
  220.         DisplayWindow(theWindow, false);
  221.         TSelectWindow(theWindow);
  222.     }
  223.     else    /* userKind */    {
  224.         if (frontToolWindow)    {
  225.             DisplayWindow(theWindow, false);
  226.             TSelectWindow(theWindow);
  227.         }
  228.         else    {
  229.             frontDocWindow = (WindowPeek)theWindow;
  230.             DisplayWindow(theWindow, true);        /* Generates Activate Event. */
  231.         }
  232.     }
  233.             
  234. }    /* TShowWindow */
  235.  
  236.  
  237.  
  238. void    THideFloats (void)        {
  239.  
  240.         WindowPeek        theWindow;
  241.         
  242.     
  243.     if (frontToolWindow)    {
  244.         theWindow = frontToolWindow;        /* Start with our top one. */
  245.         
  246.         while (theWindow && (theWindow != backToolWindow->nextWindow))        {
  247.         /* Contine until we go beyond the last floating window. */
  248.         
  249.          /* Hide the window and move on to the next: */
  250.             ShowHide((WindowPtr)theWindow, false);
  251.             theWindow = theWindow->nextWindow;
  252.         }
  253.     }    /* We have floating window(s) */
  254.     
  255. }    /* THideFloats */
  256.  
  257.  
  258.  
  259. void    TShowFloats (void)        {
  260.  
  261.         WindowPeek    theWindow;
  262.         
  263.     
  264.     if (frontToolWindow)    {
  265.         theWindow = frontToolWindow;
  266.         
  267.         while (theWindow && (theWindow != backToolWindow->nextWindow))        {
  268.             ShowHide((WindowPtr)theWindow, true);
  269.             theWindow = theWindow->nextWindow;
  270.         }
  271.     }
  272.  
  273. }    /* TShowFloats */
  274.  
  275.  
  276.  
  277. WindowPtr    TFrontWindow (short wantedKind)        {
  278.  
  279.         WindowPtr    theFrontWindow;
  280.         short        frontWKind;
  281.         
  282.         
  283.     theFrontWindow = FrontWindow();
  284.     if (theFrontWindow == nil)        return (nil);
  285.     
  286.     frontWKind = TGetWKind((WindowPeek)theFrontWindow);
  287.     
  288.     switch (wantedKind)    {
  289.         
  290.         case toolKind:
  291.             return ((WindowPtr)frontToolWindow);
  292.             break;
  293.                 
  294.         case userKind:
  295.             return ((WindowPtr)frontDocWindow);
  296.             break;
  297.                 
  298.         case systemKind:
  299.             if (frontWKind == systemKind)    return (theFrontWindow);
  300.             else                            return (nil);
  301.             break;
  302.  
  303.         case anyKind:
  304.             return (theFrontWindow);
  305.                 
  306.     }    /* switch */
  307.         
  308. }    /* TFrontWindow */
  309.  
  310.  
  311.  
  312. void    TDragWindow (WindowPtr theWindow, EventRecord *theEvent)    {
  313.                      
  314.             GrafPtr            savePort, wPort;
  315.             RgnHandle        oldClip, desktopRgn, copyWStruct;
  316.             Rect            limitRect, windStruct, contentRect, deskRect;
  317.             long            endMouse;
  318.             short            belowTop, htTB, offBottom, noDrag = -32768, hDrag, vDrag;
  319.             Point            thePt;
  320.             extern long        Sleep;
  321.             
  322.         
  323.         // If dragging with Balloon showing, Floating Window gets overwritten.  So ...
  324.         if (gBalloonsUp && frontToolWindow)        {
  325.             HideBalloons(true);
  326.         
  327.             /* Need instantaneous update because of Title Bar's balloon: */
  328.             if (gWNE)
  329.                 while ( WaitNextEvent(updateMask, theEvent, Sleep, nil) )
  330.                     HandleUpdate((WindowPtr) theEvent->message);
  331.             else
  332.                 while ( GetNextEvent(updateMask, theEvent) )
  333.                     HandleUpdate((WindowPtr) theEvent->message);
  334.         }
  335.         
  336.         GetPort(&savePort);
  337.         GetWMgrPort(&wPort);
  338.         SetPort(wPort);
  339.         
  340.         oldClip = NewRgn();
  341.         GetClip(oldClip);
  342.         desktopRgn = GetGrayRgn();
  343.         SetClip(desktopRgn);
  344.         ClipAbove((WindowPeek)theWindow);
  345.         
  346.         copyWStruct = NewRgn();
  347.         CopyRgn( ((WindowPeek)theWindow)->strucRgn, copyWStruct );
  348.         
  349.         thePt = theEvent->where;
  350.         
  351.         windStruct = (**copyWStruct).rgnBBox;
  352.         contentRect = (**((WindowPeek)theWindow)->contRgn).rgnBBox;
  353.         belowTop = thePt.v - windStruct.top;
  354.         ;
  355.         htTB = contentRect.top - 1 - windStruct.top;    // Height of Title Bar.
  356.         if (htTB <= 0)        offBottom = 20;                // ... if none.
  357.         else                offBottom = contentRect.top - thePt.v;
  358.         
  359.         GlobalToLocal(&thePt);
  360.         deskRect = (**desktopRgn).rgnBBox;
  361.         SetRect(&limitRect,
  362.                 deskRect.left + 20,
  363.                 deskRect.top + belowTop,            /* Do NOT hide top of window. */
  364.                 deskRect.right - 20,
  365.                 deskRect.bottom - offBottom );        /* Do NOT hide Title Bar. */
  366.                 
  367.         endMouse = DragGrayRgn(copyWStruct, thePt, &limitRect, &limitRect,
  368.                                noConstraint, (ProcPtr) nil);
  369.                              
  370.         SetClip(oldClip);
  371.         
  372.         vDrag = HiWord(endMouse);
  373.         hDrag = LoWord(endMouse);
  374.         if ( (vDrag != noDrag) && (hDrag != noDrag) )        {
  375.         
  376.             SetPort(theWindow);
  377.             thePt = topLeft(theWindow->portRect);
  378.             LocalToGlobal(&thePt);
  379.             MoveWindow(theWindow, thePt.h + hDrag, thePt.v + vDrag, false);
  380.                         
  381.             /* If dragging a back Document Window or a back DA
  382.             ** WITHOUT the CMD-key pressed, then bring window forward: */
  383.             
  384.             if ( !(theEvent->modifiers & cmdKey) )        {
  385.                 
  386.                     short    theWKind;
  387.                         
  388.                 theWKind = TGetWKind((WindowPeek)theWindow);
  389.                 if (theWKind == toolKind)
  390.                     ;
  391.                 else if (theWKind == userKind)    {
  392.                     if ( (WindowPeek)theWindow != frontDocWindow )
  393.                         TSelectWindow(theWindow);
  394.                 }
  395.                 else    /* systemKind */    if (theWindow != TFrontWindow(systemKind))
  396.                     SelectWindow(theWindow);
  397.             
  398.             }    /* CMD-key NOT pressed */
  399.             
  400.         }    /* Dragged a little before releasing Mouse within bounds */
  401.         
  402.         DisposeRgn(copyWStruct);
  403.         DisposeRgn(oldClip);
  404.         SetPort(savePort);
  405.         
  406.         ShowBalloons(gBalloonsUp);    
  407.         
  408. }    /* TDragWindow */
  409.  
  410.  
  411.  
  412. short    TGetWKind (WindowPeek theWindow)        {
  413.  
  414.         short    theWKind;
  415.         
  416.     
  417.     theWKind = theWindow->windowKind;
  418.     
  419.     if (theWKind < 0)                    theWKind = systemKind;
  420.     
  421.     else if (theWKind == dialogKind)    theWKind = userKind;
  422.     
  423.     else if (theWKind == toolKind)        theWKind = toolKind;
  424.  
  425.     else if (theWKind >= userKind)        theWKind = userKind;
  426.                      
  427.     return (theWKind);
  428.     
  429. }    /* TGetWKind */
  430.  
  431.  
  432.  
  433. void    THiliteTools (Boolean hilite)        {
  434.  
  435.         WindowPeek        loopWindow;
  436.         Boolean            done = false;
  437.         
  438.         
  439.     if (frontToolWindow != nil)        {
  440.         for ( loopWindow = frontToolWindow;
  441.               !done && (loopWindow != nil);
  442.               loopWindow = loopWindow->nextWindow )        {
  443.               
  444.             if ( (TGetWKind(loopWindow) == toolKind) &&
  445.                  loopWindow->visible )        {
  446.                 HiliteWindow((WindowPtr)loopWindow, hilite);
  447.                 if (loopWindow == backToolWindow)    done = true;
  448.             }
  449.             
  450.         }    /* for-loop */
  451.     }
  452.             
  453. }    /* THiliteTools */
  454.  
  455.  
  456.  
  457. void    TSuspend (void)        {
  458.  
  459.     
  460.     if (frontDocWindow)        {
  461.         HiliteWindow((WindowPtr)frontDocWindow, false);
  462.         DoDeactivate((WindowPtr)frontDocWindow);
  463.     }
  464.     
  465.     THideFloats();
  466.     
  467. }    /* TSuspend */
  468.  
  469.  
  470.  
  471. void    TResume (void)        {
  472.  
  473.  
  474.     TShowFloats();
  475.     
  476.     if (frontDocWindow)        TSelectWindow((WindowPtr) frontDocWindow);
  477.     else                    THiliteTools(true);
  478.     
  479. }    /* TResume */
  480.  
  481.  
  482.  
  483. WindowPeek        TNextVisWindow (short wantedKind, WindowPeek thePWindow)        {
  484.  
  485.         WindowPeek    loopWindow, wantedWindow;
  486.         
  487.         
  488.     for (wantedWindow = nil, loopWindow = thePWindow->nextWindow;
  489.          (wantedWindow == nil) && (loopWindow != nil);
  490.          loopWindow = loopWindow->nextWindow)    {
  491.         
  492.         if (loopWindow->visible)
  493.             if ( (wantedKind == anyKind) ||
  494.                  (wantedKind == TGetWKind(loopWindow)) )
  495.                 wantedWindow = loopWindow;
  496.                 
  497.     }
  498.     
  499.     return (wantedWindow);
  500.     
  501. }    /* TNextVisWindow */
  502.  
  503.  
  504.  
  505. WindowPeek        TPrevVisWindow (WindowPeek thePWindow)        {
  506.  
  507.         WindowPeek    loopWindow, prevWindow, theFrontWindow;
  508.         Boolean        done = false;
  509.         
  510.         
  511.     theFrontWindow = (WindowPeek)FrontWindow();
  512.     
  513.     if ( !theFrontWindow->visible || (thePWindow == theFrontWindow) )    return (nil);
  514.        
  515.     prevWindow = theFrontWindow;
  516.     loopWindow = prevWindow->nextWindow;
  517.     
  518.     while (!done && (loopWindow != nil))        {
  519.         if (loopWindow == thePWindow)    done = true;
  520.         else    {
  521.             if (loopWindow->visible)    prevWindow = loopWindow;
  522.             loopWindow = loopWindow->nextWindow;
  523.         }
  524.     }
  525.     
  526.     return (prevWindow);
  527.     
  528. }    /* TPrevVisWindow */
  529.  
  530.  
  531.  
  532. void    TBringForward (WindowPeek thePWindow, WindowPeek behindWindow,
  533.                        Boolean waitWithCalc)    {
  534.                       
  535.         RgnHandle    coveredRgn;
  536.         GrafPtr        savePort;
  537.         
  538.             
  539.     GetPort(&savePort);
  540.     SetPort((WindowPtr)thePWindow);
  541.     ;
  542.     coveredRgn = NewRgn();
  543.  
  544.     // visible part of portRect:    
  545.     CopyRgn(((WindowPtr)thePWindow)->visRgn, coveredRgn);
  546.     OffsetRgn(coveredRgn,                    /* LocalToGlobal */
  547.               (**(thePWindow->contRgn)).rgnBBox.left,
  548.               (**(thePWindow->contRgn)).rgnBBox.top);
  549.     ;
  550.     // result = what's covered by window(s) in front:
  551.     DiffRgn(thePWindow->strucRgn, coveredRgn, coveredRgn);
  552.  
  553.     SendBehind((WindowPtr)thePWindow, (WindowPtr)behindWindow);
  554.     
  555.     /* _PaintOne sets thePort to the Window Manager Port,
  556.     ** so we must set thePort back to theWindow before
  557.     ** we call _CalcVisBehind.                            */
  558.     
  559.     PaintOne(thePWindow, coveredRgn);
  560.  
  561.     if (!waitWithCalc)        {
  562.         SetPort((WindowPtr)thePWindow);
  563.         CalcVisBehind(thePWindow, coveredRgn);
  564.     }
  565.     
  566.     DisposeRgn(coveredRgn);
  567.     ;
  568.     SetPort(savePort);
  569.  
  570. }    /* TBringForward */
  571.  
  572.  
  573.  
  574. void    TSendDAsBack (WindowPeek behindWindow)        {
  575.  
  576.         WindowPeek        loopWindow = WindowList, daWindow, origBehind;
  577.         RgnHandle        overlap;
  578.         
  579.         
  580.     origBehind = behindWindow;
  581.     
  582.     overlap = NewRgn();
  583.     
  584.     while ( (loopWindow != nil) && (loopWindow != origBehind) )    {
  585.     
  586.         if ( (TGetWKind(loopWindow) == systemKind) && loopWindow->visible )    {
  587.             daWindow = loopWindow;
  588.             TBringForward(daWindow, behindWindow, postponeCalc);
  589.             HiliteWindow((WindowPtr) daWindow, false);
  590.             UnionRgn(overlap, daWindow->strucRgn, overlap);
  591.             
  592.             // ... so we maintain the same ordering of DAs we started with:
  593.             behindWindow = daWindow;
  594.  
  595.             /* loopWindow, our DA, has now been moved behind,
  596.             ** so we must continue with the window that was
  597.             ** FORMERLY behind our USED-TO-BE front DA.  This
  598.             ** latter window is now on top:                      */
  599.             
  600.             loopWindow = WindowList;
  601.             continue    /* with the while-loop IMMEDIATELY */    ;
  602.         }
  603.         
  604.         loopWindow = loopWindow->nextWindow;
  605.         
  606.     }    /* end: while */
  607.     
  608.     CalcVisBehind(origBehind, overlap);
  609.     DisposeRgn(overlap);
  610.     
  611. }    /* TSendDAsBack */
  612.  
  613.  
  614.  
  615.  
  616. /*    { end file "floatingWindow.c" }  */
  617.